package com.personal.datacompare.api;

import java.util.ArrayList;
import java.util.List;

import com.personal.core.data.DataRow;
import com.personal.core.data.DataTables;
import com.personal.core.data.DataTable;
import com.personal.core.utils.Assert;
import com.personal.datacompare.config.CompareDataTableConfig;
import com.personal.datacompare.config.CompareDataTableConfigApp;
import com.personal.datacompare.tree.AbstractCompareTree;
import com.personal.datacompare.tree.ITree;
import com.personal.dataconvert.DataSet2Excel;
import com.personal.dataconvert.DataTable2Html;
import com.personal.dataconvert.util.ExcelHtmlUtil;

/**
 * 复杂对比合并DataTable
 * @author cuibo
 */
public class CompareTree
{
    /**
     * 批量导出对比结果 该方法是一个静态方法 如果需要导出多张的对比结果，需要构建多个该对象，分别拿到结果存入一个DataSet中 然后调用该方法导出
     * @param ds
     * @throws Exception
     */
    public static byte[] batchExportCompareResult(DataTables ds) throws Exception
    {
        if (ds == null || ds.isEmpty())
        {
            return null;
        }
        DataSet2Excel exportExcel = new DataSet2Excel.Builder().setDataSet(ds).setRecalWidth(true).build();
        return exportExcel.exportExcel();
    }

    /** 配置ID */
    private String configId;
    /** 对比合并配置 */
    private CompareDataTableConfig tableConfig;
    /** 合并配置的树集合 */
    private List<AbstractCompareTree> trees;
    /** 是否已经合并对比 */
    private boolean hasCompare = false;
    /** 合并对比结果 */
    private DataTable result;
    /** 合并对比结果树 */
    private AbstractCompareTree resultTree;

    public CompareTree(CompareDataTableConfig tableConfig, AbstractCompareTree... trees)
    {
        super();
        this.tableConfig = tableConfig;
        this.trees = new ArrayList<AbstractCompareTree>();
        if (trees != null && trees.length > 0)
        {
            for (AbstractCompareTree tree : trees)
            {
                this.trees.add(tree);
            }
        }
    }

    public CompareTree(CompareDataTableConfig tableConfig, List<AbstractCompareTree> trees)
    {
        super();
        this.tableConfig = tableConfig;
        this.trees = trees;
    }

    public CompareTree(String configId, AbstractCompareTree... trees)
    {
        super();
        this.configId = configId;
        this.trees = new ArrayList<AbstractCompareTree>();
        if (trees != null && trees.length > 0)
        {
            for (AbstractCompareTree tree : trees)
            {
                this.trees.add(tree);
            }
        }
    }

    public CompareTree(String configId, List<AbstractCompareTree> trees)
    {
        super();
        this.configId = configId;
        this.trees = trees;
    }

    /**
     * 导出对比结果
     * @return
     * @throws Exception
     */
    public byte[] exportCompareResult() throws Exception
    {
        if (!hasCompare)
        {
            compare();
        }
        DataTables ds = new DataTables();
        ds.add(result);
        DataSet2Excel exportExcel = new DataSet2Excel.Builder().setDataSet(ds).setRecalWidth(true)
                .setSplitFlag(ExcelHtmlUtil.REPLACEPOINTFLAG).build();
        return exportExcel.exportExcel();
    }

    /**
     * 获取合并对比结果
     * @return
     */
    public DataTable getCompareResult() throws Exception
    {
        if (!hasCompare)
        {
            compare();
        }
        if (result == null)
        {
            result = resultTree == null ? null : resultTree.toDataTable();
        }
        return result;
    }

    /**
     * 获取合并对比结果
     * @return
     */
    public String getCompareResultAsHtml() throws Exception
    {
        if (!hasCompare)
        {
            compare();
        }
        return new DataTable2Html.Builder().setDataTable(getCompareResult())
                .setSplitFlag(ExcelHtmlUtil.REPLACEPOINTFLAG).build().createHtml();
    }

    /**
     * 获取统计结果树
     * @return
     * @throws Exception
     */
    public AbstractCompareTree getCompareResultAsTree() throws Exception
    {
        if (!hasCompare)
        {
            compare();
        }
        return resultTree;
    }

    private void compare() throws Exception
    {
        if (hasCompare)
        {
            return;
        }
        if (tableConfig == null)
        {
            tableConfig = CompareDataTableConfigApp.getCompareDataTableConfig(configId);
        }
        Assert.isNotNull(tableConfig, "获取对比合并配置失败！");
        compareImpl();
        hasCompare = true;
    }

    private void compareImpl() throws Exception
    {
        if (trees == null || trees.isEmpty())
        {
            return;
        }
        // 设置 tableConfig
        for (AbstractCompareTree compareTree : trees)
        {
            compareTree.setTableConfig(tableConfig);
        }
        if (trees.size() == 1)
        {
            resultTree = trees.get(0);
            return;
        }
        // 以第一个为标杆
        AbstractCompareTree bgTree = trees.get(0);
        List<ITree<DataTable, DataRow>> otherTrees = new ArrayList<ITree<DataTable, DataRow>>();
        for (ITree<DataTable, DataRow> iTree : trees)
        {
            // 移除标杆
            if (iTree == trees.get(0))
            {
                continue;
            }
            otherTrees.add(iTree);
        }
        // 合并树
        resultTree = bgTree.combine(otherTrees);
    }
}
